package com.atguigu.gmall.oms.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.common.exception.GmallUserException;
import com.atguigu.gmall.oms.entity.OrderItemEntity;
import com.atguigu.gmall.oms.feign.GmallSmsClient;
import com.atguigu.gmall.oms.feign.GmallUmsClient;
import com.atguigu.gmall.oms.service.OrderItemService;
import com.atguigu.gmall.order.vo.OrderConfirmItemVO;
import com.atguigu.gmall.order.vo.OrderSubmitVO;
import com.atguigu.gmall.sms.entity.SkuBoundsEntity;
import com.atguigu.gmall.ums.entity.UserAddressEntity;
import com.atguigu.gmall.ums.entity.UserEntity;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.gmall.common.bean.PageResultVo;
import com.atguigu.gmall.common.bean.PageParamVo;

import com.atguigu.gmall.oms.mapper.OrderMapper;
import com.atguigu.gmall.oms.entity.OrderEntity;
import com.atguigu.gmall.oms.service.OrderService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;


@Service("orderService")
public class OrderServiceImpl extends ServiceImpl<OrderMapper, OrderEntity> implements OrderService {
    @Resource
    GmallUmsClient umsClient;
    @Resource
    GmallSmsClient smsClient;
    @Override
    public PageResultVo queryPage(PageParamVo paramVo) {
        IPage<OrderEntity> page = this.page(
                paramVo.getPage(),
                new QueryWrapper<OrderEntity>()
        );

        return new PageResultVo(page);
    }
    @Transactional
    @Override
    public Long createOrder(OrderSubmitVO orderSubmitVO) {
        //查询用户
        CompletableFuture<UserEntity> c1 = CompletableFuture.supplyAsync(() -> {
            //查询用户表: ums查询id对应用户的姓名
            UserEntity userEntity = umsClient.queryUserById(orderSubmitVO.getUserId()).getData();
            if (userEntity == null) {
                throw new GmallUserException("用户不存在", 1025);
            }
            return userEntity;
        });
        //保存订单
        CompletableFuture<OrderEntity> c2 = c1.thenApply((userEntity) -> {
            CompletableFuture<OrderEntity> cf1 = CompletableFuture.supplyAsync(() -> {
                //保存订单
                OrderEntity order = new OrderEntity();
                order.setUserId(orderSubmitVO.getUserId());
                order.setOrderSn(orderSubmitVO.getOrderToken());
                order.setCreateTime(new Date());
                order.setTotalAmount(orderSubmitVO.getTotalPrice());
                order.setPayAmount(orderSubmitVO.getTotalPrice());
                order.setFreightAmount(new BigDecimal(0));

                order.setStatus(0); //0->待付款；1->待发货；2->已发货；3->已完成；4->已关闭；5->无效订单
                order.setDeliveryCompany(orderSubmitVO.getDeliveryCompany());
                UserAddressEntity userAddressEntity = orderSubmitVO.getAddress();
                order.setReceiverAddress(userAddressEntity.getAddress());
                order.setReceiverPhone(userAddressEntity.getPhone());
                order.setReceiverPostCode(userAddressEntity.getPostCode());
                order.setReceiverRegion(userAddressEntity.getRegion());
                order.setReceiverCity(userAddressEntity.getCity());
                order.setReceiverProvince(userAddressEntity.getProvince());
                order.setReceiverName(userAddressEntity.getName());
                order.setUsername(userEntity.getUsername());
                BigDecimal integrationAmount = new BigDecimal(orderSubmitVO.getBounds()).divide(new BigDecimal(100));
                order.setIntegrationAmount(integrationAmount);//积分抵扣金额：
                //查询计算积分： sms查询sku的 积分营销信息
                List<OrderConfirmItemVO> submitVOItems = orderSubmitVO.getItems();
                order.setRemark(submitVOItems.get(0).getTitle());
                List<SkuBoundsEntity> skuBoundsEntities = submitVOItems.stream().map(submitVOItem -> {
                    String skuId = submitVOItem.getSkuId();
                    //根据skuId查询 sms中的积分表
                    SkuBoundsEntity skuBoundsEntity = smsClient.querySkuBounds(Long.parseLong(skuId)).getData();
                    return skuBoundsEntity;
                }).filter(skuBoundsEntity -> skuBoundsEntity != null).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(skuBoundsEntities)) {
                    order.setIntegration(0);
                    order.setGrowth(0);
                } else {
                    order.setIntegration(skuBoundsEntities.stream().map(SkuBoundsEntity::getBuyBounds)
                            .reduce(BigDecimal::add).get().intValue());
                    //计算成长积分
                    order.setGrowth(skuBoundsEntities.stream().map(SkuBoundsEntity::getGrowBounds)
                            .reduce(BigDecimal::add).get().intValue());
                }

                this.save(order);
                //保存订单项:submitVOItems 一个订单项对应一个购物项对应一个sku
                Map<Long, BigDecimal> boundsMap = skuBoundsEntities.stream().collect(Collectors.toMap(SkuBoundsEntity::getSkuId, SkuBoundsEntity::getBuyBounds));
                Map<Long, BigDecimal> growMap = skuBoundsEntities.stream().collect(Collectors.toMap(SkuBoundsEntity::getSkuId, SkuBoundsEntity::getGrowBounds));
                Long orderId = order.getId();
                List<OrderItemEntity> orderItems = submitVOItems.stream().map(submitVOItem->{
                    OrderItemEntity orderItemEntity = new OrderItemEntity();
                    orderItemEntity.setOrderId(orderId);
                    orderItemEntity.setOrderSn(orderSubmitVO.getOrderToken());
                    //
                    Long skuId = Long.parseLong(submitVOItem.getSkuId());
                    orderItemEntity.setSkuId(skuId);
                    orderItemEntity.setSkuName(submitVOItem.getTitle());
                    orderItemEntity.setSkuPic(submitVOItem.getDefaultImage());
                    orderItemEntity.setSkuPrice(submitVOItem.getPrice());
                    orderItemEntity.setSkuQuantity(submitVOItem.getCount());
                    orderItemEntity.setSkuAttrsVals(JSON.toJSONString(submitVOItem.getSaleAttrs()));
                    orderItemEntity.setGiftIntegration(boundsMap.containsKey(skuId)?boundsMap.get(skuId).intValue()
                            :0);
                    orderItemEntity.setGiftGrowth(growMap.containsKey(skuId)?growMap.get(skuId).intValue()
                            :0);

                    return orderItemEntity;
                }).collect(Collectors.toList());

                orderItemService.saveBatch(orderItems);
                return order;
            });
            CompletableFuture<Void> cf2 = cf1.thenAcceptAsync((order) -> {
                //扣除用户使用的积分   增加用户的购买本次产品的积分
                userEntity.setIntegration(userEntity.getIntegration() - orderSubmitVO.getBounds()
                        + order.getIntegration());//之前的购物积分-订单使用的购物积分+本次订单累加的购物积分
                userEntity.setGrowth(userEntity.getGrowth() + order.getGrowth());
                //更新用户表：用户积分
                umsClient.update(userEntity);
            });
            CompletableFuture.allOf(cf1,cf2).join();

            try {
                return cf1.get();
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        });


        CompletableFuture.allOf(c1,c2).join();
        try {
            return c2.get().getId();
        } catch (Exception e) {
            return null;
        }
    }
    @Resource
    OrderItemService orderItemService;
}